/*
 * @Author: zxc
 * @Date: 2020-08-05 18:58:19
 * @LastEditTime: 2020-08-06 15:53:56
 * @LastEditors: zxc
 * @Description: 字典
 */
export const defaultToString = (item) => {
  if (item === null) {
    return "NULL";
  } else if (item === undefined) {
    return "UNDEFINED";
  } else if (typeof item === "string" || item instanceof String) {
    return `${item}`;
  }
  return item.toString();
};
export class ValuePair {
  constructor(key, value) {
    this.key = key;
    this.value = value;
  }
  toString() {
    return `[#${this.key}: ${this.value}]`;
  }
}

export class Dictionary {
  constructor(toStrFn = defaultToString) {
    this.toStrFn = toStrFn;
    this.table = {};
  }

  // 添加元素
  set(key, value) {
    if (key !== null && value !== null) {
      const tableKey = this.toStrFn(key);
      this.table[tableKey] = new ValuePair(key, value);
      return true;
    }
    return false;
  }

  // 是否存在
  haskey(key) {
    return this.table[this.toStrFn(key)] != null;
  }

  // 检索
  get(key) {
    return this.haskey(key) ? this.table[this.toStrFn(key)] : undefined;
  }

  // 移除
  remove(key) {
    if (this.haskey(key)) {
      delete this.table[this.toStrFn(key)];
      return true;
    }
    return false;
  }

  values() {
    return this.keyValues().map((valuePair) => valuePair.value);
  }
  keys() {
    return this.keyValues().map((valuePair) => valuePair.key);
  }
  keyValues() {
    return Object.values(this.table);
  }
  forEach(callbackFn) {
    const valuePairs = this.keyValues();
    for (let i = 0; i < valuePairs.length; i++) {
      const result = callbackFn(valuePairs[i].key, valuePairs[i].value);
      if (result === false) {
        break;
      }
    }
  }
  isEmpty() {
    return this.size() === 0;
  }
  size() {
    return Object.keys(this.table).length;
  }
  clear() {
    this.table = {};
  }
  toString() {
    if (this.isEmpty()) {
      return '';
    }
    const valuePairs = this.keyValues();
    let objString = `${valuePairs[0].toString()}`;
    for (let i = 1; i < valuePairs.length; i++) {
      objString = `${objString},${valuePairs[i].toString()}`;
    }
    return objString;
  }
  getTable(){
    return this.table
  }
}

const s = new Dictionary()
s.set('a','fk')
s.set('b','dk')
s.set('c','sk')
// console.log(s.getTable())
// console.log(s.toString())
// console.log(s.keyValues())